package com.lc.builder;

import com.lc.bean.Constants;
import com.lc.bean.FieldInfo;
import com.lc.bean.TableInfo;
import com.lc.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;

/**
 * 功能：
 * 作者：lc
 * 日期：2024/8/6 17:56
 */
public class BuildServiceImpl {
    private static final Logger logger = LoggerFactory.getLogger(BuildService.class);

    public static void execute(TableInfo tableInfo) {
        String beanName = tableInfo.getBeanName();
        String pathName = beanName + "ServiceImpl";
        String implementName = beanName + "Service";
        String mapperName = beanName + "Mapper";
        String beanMapperName = StringUtils.lowerCaseFirstLetter(mapperName);
        File folder = new File(Constants.PATH_SERVICEIMPL);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        File poFile = new File(folder, pathName + ".java");
        OutputStream out = null;
        OutputStreamWriter outw = null;
        BufferedWriter bw = null;
        try {
            out = Files.newOutputStream(poFile.toPath());
            outw = new OutputStreamWriter(out, "utf8");
            bw = new BufferedWriter(outw);
            bw.write("package " + Constants.PACKAGE_SERVICEIMPL + ";\n");
            bw.newLine();
            bw.write("import " + Constants.PACKAGE_PO + "." + beanName + ";\n");
            bw.write("import " + Constants.PACKAGE_QUERY + "." + tableInfo.getBeanParamName() + ";\n");
            bw.write("import " + Constants.PACKAGE_QUERY + ".SimplePage;\n");
            bw.write("import " + Constants.PACKAGE_VO + "." + "PaginationResultVO;\n");
            bw.write("import " + Constants.PACKAGE_ENUMS + ".PageSize;");
            bw.write("import " + Constants.PACKAGE_MAPPER + "." + mapperName + ";\n");
            bw.write("import " + Constants.PACKAGE_SERVICE + "." + implementName + ";\n");
            bw.write("import org.springframework.stereotype.Service;\n");

            bw.newLine();
            bw.write("import javax.annotation.Resource;\n");
            bw.write("import java.util.List;\n\n");
            BuildQuery.havaBeanField(tableInfo, bw);
            if (tableInfo.getHaveDate() || tableInfo.getHaveDateTime()) {
                bw.write("import java.util.Date;\n" +
                        Constants.BEAN_DATE_FORMAT_CLASS +
                        "\n" +
                        "import com.lc.enums.DateTimePatterEnum;\n" +
                        "import com.lc.utils.DateUtils;\n" +
                        Constants.BEAN_DATE_UNFORMAT_CLASS +
                        "\n");
            }
            bw.write("\n@Service(\"" + StringUtils.lowerCaseFirstLetter(implementName) + "\")\n");
            bw.write("public class " + pathName + " implements " + implementName + " {\n");
            bw.write("\t@Resource\n" +
                    "\tprivate " + mapperName + "<" + beanName + ", " + tableInfo.getBeanParamName() + "> " +
                    beanMapperName + ";\n");
            BuildComment.createFieldComment(bw, "根据条件查询列表");
            bw.write("\t@Override\n");
            bw.write("\tpublic List<" + beanName + "> selectAllByParam(" + tableInfo.getBeanParamName() + " param) {\n");
            bw.write("\t\treturn this." + beanMapperName + ".selectList(param);\n");
            bw.write("\t}\n");
            BuildComment.createFieldComment(bw, "根据条件查询数量");
            bw.write("\t@Override\n");
            bw.write("\tpublic Integer selectCountByParam(" + tableInfo.getBeanParamName() + " param) {\n");
            bw.write("\t\treturn this." + beanMapperName + ".selectCount(param);\n");
            bw.write("\t}\n");

            BuildComment.createFieldComment(bw, "分页查询");
            bw.write("\t@Override\n");
            bw.write("\tpublic PaginationResultVO<" + tableInfo.getBeanName() + "> selectAllBtPage(" + tableInfo.getBeanParamName() + " param) {\n");
            bw.write("\t\tInteger count = this.selectCountByParam(param);\n" +
                    "\t\tInteger pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();\n" +
                    "\t\tSimplePage page = new SimplePage(param.getPageNo(), count, pageSize);\n" +
                    "\t\tparam.setSimplePage(page);\n" +
                    "\t\tList<" + beanName + "> list = this.selectAllByParam(param);\n" +
                    "\t\treturn new PaginationResultVO<>(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);\n");
            bw.write("\t}\n");

            BuildComment.createFieldComment(bw, "新增");
            bw.write("\t@Override\n");
            bw.write("\tpublic Integer add(" + tableInfo.getBeanParamName() + " bean) {\n");
            bw.write("\t\treturn this." + beanMapperName + ".insert(bean);\n");
            bw.write("\t}\n");

            BuildComment.createFieldComment(bw, "新增或者更新");
            bw.write("\t@Override\n");
            bw.write("\tpublic Integer addOrUpdate(" + tableInfo.getBeanParamName() + " bean) {\n");
            bw.write("\t\treturn this." + beanMapperName + ".insertOrUpdate(bean);\n");
            bw.write("\t}\n");

            BuildComment.createFieldComment(bw, "批量新增");
            bw.write("\t@Override\n");
            bw.write("\tpublic Integer addBatch(List<" + tableInfo.getBeanParamName() + "> listBean) {\n");
            bw.write("\t\tif (listBean == null || listBean.isEmpty()) {\n" +
                    "\t\t\treturn 0;\n" +
                    "\t\t}\n" +
                    "\t\treturn this." + beanMapperName + ".insertBatch(listBean);\n");
            bw.write("\t}\n");

            BuildComment.createFieldComment(bw, "批量新增/修改");
            bw.write("\t@Override\n");
            bw.write("\tpublic Integer addOrUpdateBatch(List<" + tableInfo.getBeanParamName() + "> listBean) {\n");
            bw.write("\t\tif (listBean == null || listBean.isEmpty()) {\n" +
                    "\t\t\treturn 0;\n" +
                    "\t\t}\n" +
                    "\t\treturn this." + beanMapperName + ".insertOrUpdateBatch(listBean);\n");
            bw.write("\t}\n");

            Map<String, List<FieldInfo>> keyIndexMap = tableInfo.getKeyIndexMap();
            for (Map.Entry<String, List<FieldInfo>> entry :
                    keyIndexMap.entrySet()) {
                List<FieldInfo> keyFieldInfoList = entry.getValue();
                int index = 0;
                StringBuffer methodName = new StringBuffer();
                StringBuffer methodParam = new StringBuffer();
                StringBuffer methodBatch = new StringBuffer();
                String lowMethodName = null;
                for (FieldInfo fieldInfo :
                        keyFieldInfoList) {
                    index++;
                    if (lowMethodName == null) {
                        lowMethodName = fieldInfo.getPropertyName();
                    } else {
                        lowMethodName = "id";
                    }
                    methodName.append(StringUtils.upperCaseFirstLetter(fieldInfo.getPropertyName()));
                    methodParam.append(fieldInfo.getJavaType()).append(" ").append(fieldInfo.getPropertyName());
                    methodBatch.append(fieldInfo.getJavaType()).append("[] ").append(fieldInfo.getPropertyName()).append("s");
                    if (index < keyFieldInfoList.size()) {
                        methodName.append("And");
                    }
                    if (index < keyFieldInfoList.size()) {
                        methodParam.append(", ");
                        methodBatch.append(", ");
                    }

                }
                BuildComment.createFieldComment(bw, "根据" + methodName + "查询");
                bw.write("\t@Override\n");
                bw.write("\tpublic " + beanName + " getBy" + methodName + "(" + methodParam + ") {\n");
                bw.write("\t\treturn this." + beanMapperName + ".selectBy" + methodName + "(" + lowMethodName + ");\n");
                bw.write("\t}\n");


                BuildComment.createFieldComment(bw, "根据" + methodName + "更新");
                bw.write("\t@Override\n");
                bw.write("\tpublic Integer updateBy" + methodName + "(" + beanName + " bean, " + methodParam + ") {\n");
                bw.write("\t\treturn this." + beanMapperName + ".updateBy" + methodName + "(bean," + lowMethodName + ");\n");
                bw.write("\t}\n");


                BuildComment.createFieldComment(bw, "根据" + methodName + "删除");
                bw.write("\t@Override\n");
                bw.write("\tpublic Integer deleteBy" + methodName + "(" + methodParam + ") {\n");
                bw.write("\t\treturn this." + beanMapperName + ".deleteBy" + methodName + "(" + lowMethodName + ");\n");
                bw.write("\t}\n");


                BuildComment.createFieldComment(bw, "根据" + methodName + "批量删除");
                bw.write("\t@Override\n");
                bw.write("\tpublic Integer deleteBy" + methodName + "s(" + methodBatch + ") {\n");
                bw.write("\t\treturn this." + beanMapperName + ".deleteBy" + methodName + "s(" + lowMethodName + "s);\n");
                bw.write("\t}\n");
            }

            bw.write("\n}");

            bw.flush();
        } catch (Exception e) {
            logger.error("创建Service层失败~", e);
        } finally {
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (outw != null) {
                try {
                    outw.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }

    }
}
